package com.novel.controller;

import com.novel.common.exception.job.TaskException;
import com.novel.domain.SysJob;
import com.novel.framework.annotation.Log;
import com.novel.framework.base.BaseController;
import com.novel.framework.enums.BusinessType;
import com.novel.framework.result.Result;
import com.novel.framework.utils.excel.ExcelUtils;
import com.novel.framework.validate.groups.AddGroup;
import com.novel.framework.validate.groups.EditGroup;
import com.novel.framework.web.page.TableDataInfo;
import com.novel.service.SysJobService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.SchedulerException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 调度任务信息操作处理
 *
 * @author novel
 * @date 2020/3/2
 */
@RestController
@RequestMapping("/monitor/job")
public class SysJobController extends BaseController {

    private final SysJobService jobService;

    public SysJobController(SysJobService jobService) {
        this.jobService = jobService;
    }

    /**
     * 获取任务列表
     *
     * @param job 查询条件
     * @return 列表数据
     */
    @RequiresPermissions("monitor:job:list")
    @GetMapping("/list")
    public TableDataInfo list(SysJob job) {
        startPage();
        List<SysJob> list = jobService.selectJobList(job);
        return getDataTable(list);
    }

    /**
     * 删除任务
     *
     * @param ids 任务id数组
     * @return 删除结果
     * @throws SchedulerException 任务调度异常
     */
    @Log(title = "定时任务", businessType = BusinessType.DELETE)
    @RequiresPermissions("monitor:job:remove")
    @DeleteMapping("/remove")
    public Result remove(Long[] ids) throws SchedulerException {
        return toAjax(jobService.deleteJobByIds(ids));
    }

    /**
     * 任务调度状态修改
     *
     * @param job 任务信息
     * @return 更新结果
     * @throws SchedulerException 任务调度异常
     */
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @RequiresPermissions("monitor:job:changeStatus")
    @PutMapping("/changeStatus")
    public Result changeStatus(SysJob job) throws SchedulerException {
        SysJob newJob = jobService.selectJobById(job.getId());
        newJob.setStatus(job.getStatus());
        return toAjax(jobService.changeStatus(newJob));
    }

    /**
     * 任务调度立即执行一次
     *
     * @param job 任务信息
     * @return 执行结果
     * @throws SchedulerException 任务调度异常
     */
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @RequiresPermissions("monitor:job:changeStatus")
    @PostMapping("/run")
    public Result run(SysJob job) throws SchedulerException {
        return toAjax(jobService.run(job), "执行成功", "执行失败");
    }

    /**
     * 新增保存调度
     *
     * @param job 任务信息
     * @return 增加结果
     * @throws SchedulerException 任务调度异常
     * @throws TaskException      任务执行异常
     */
    @Log(title = "定时任务", businessType = BusinessType.INSERT)
    @RequiresPermissions("monitor:job:add")
    @PostMapping("/add")
    public Result addSave(@Validated(AddGroup.class) SysJob job) throws SchedulerException, TaskException {
        job.setCreateBy(getUserName());
        return toAjax(jobService.insertJob(job));
    }

    /**
     * 修改保存调度
     *
     * @param job 任务信息
     * @return 修改结果
     * @throws SchedulerException 任务调度异常
     * @throws TaskException      任务执行异常
     */
    @Log(title = "定时任务", businessType = BusinessType.UPDATE)
    @RequiresPermissions("monitor:job:edit")
    @PutMapping("/edit")
    public Result editSave(@Validated(EditGroup.class) SysJob job) throws SchedulerException, TaskException {
        job.setUpdateBy(getUserName());
        return toAjax(jobService.updateJob(job));
    }

    /**
     * 校验cron表达式是否有效
     *
     * @param job 包含cron的任务信息
     * @return 校验结果
     */
    @GetMapping("/checkCronExpressionIsValid")
    public Result checkCronExpressionIsValid(SysJob job) {
        return toAjax((Object) jobService.checkCronExpressionIsValid(job.getCronExpression()));
    }

    /**
     * 导出定时任务信息
     *
     * @param job 定时任务查询条件
     * @return 导出文件结果
     */
    @Log(title = "定时任务", businessType = BusinessType.EXPORT)
    @RequiresPermissions("monitor:job:export")
    @GetMapping("/export")
    public Result export(SysJob job) {
        startPage();
        List<SysJob> list = jobService.selectJobList(job);
        String fileName = ExcelUtils.exportExcelToFile(list, "定时任务", SysJob.class);
        Map<String, Object> map = new HashMap<>(1);
        map.put("fileName", fileName);
        return toAjax(map);
    }
}
